<!DOCTYPE html> <!-- -*- html -*- -->
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1">
  <title>Least Squares Solutions</title>
  <link rel="shortcut icon" href="img/gatech.gif"/>

  
      <link rel="stylesheet" href="css/demo.css?vers=2759ff">
  

  <style>
      
  </style>

</head>
<body>
    

    
        <script src="js/demo.js?vers=77646a"></script>
    

    <script type="text/javascript">
        "use strict";
        DomReady.ready(function() {

        var Emat, a, bColor, bHatColor, colBasis, labels, linComboColor, matrix, nulBasis, numVecs, projection, range, ref, ref1, ref2, rref, size, solution, solve, spanVecColor, subName, surfaceColor, texLabels, vecLabel, vector, vector1, vector2, vector3, vectors;

range = urlParams.get('range', 'float', 10);

vector1 = urlParams.get('v1', 'float[]', [3, 0, 0]);

vector2 = urlParams.get('v2', 'float[]', [0, 3, 0]);

vector3 = urlParams.get('v3', 'float[]', [3, 3, 0]);

vector = urlParams.get('vec', 'float[]', [5, 5, 5]);

size = vector1.length;

surfaceColor = new Color("violet");

spanVecColor = new Color("orange");

linComboColor = new Color("green");

bColor = new Color("red");

bHatColor = new Color("blue");

numVecs = 2;

if (urlParams.v3 != null) {
  numVecs = 3;
} else if ((urlParams.v1 != null) && (urlParams.v2 == null)) {
  numVecs = 1;
}

matrix = [vector1.slice(), vector2.slice(), vector3.slice()].slice(0, numVecs);

rref = [vector1.slice(), vector2.slice(), vector3.slice()].slice(0, numVecs);

ref = rowReduce(rref), nulBasis = ref[0], colBasis = ref[1], Emat = ref[2], solve = ref[3];

if (vector1[2] == null) {
  vector1[2] = 0;
}

if (vector2[2] == null) {
  vector2[2] = 0;
}

if (vector3[2] == null) {
  vector3[2] = 0;
}

vectors = [vector1, vector2, vector3].slice(0, numVecs);

solution = [0, 0, 0].slice(0, numVecs);

projection = [0, 0, 0];

labels = urlParams.get('labels', 'str[]', ['v1', 'v2', 'v3']);

labels = labels.slice(0, numVecs);

texLabels = (function() {
  var j, len, results;
  results = [];
  for (j = 0, len = labels.length; j < len; j++) {
    a = labels[j];
    results.push(a.replace(/(\D+)/, '$1_'));
  }
  return results;
})();

vecLabel = (ref1 = urlParams.vecLabel) != null ? ref1 : 'b';

subName = (ref2 = urlParams.subname) != null ? ref2 : 'W';

window.demo = new (size === 2 ? Demo2D : Demo)({}, function() {
  var clipCube, computeOut, linCombo, matrixElt, nulSpace, str, subspace, tmpVec, updateCaptions, vectorElt, view;
  window.mathbox = this.mathbox;
  view = this.view({
    axes: false,
    grid: false,
    viewRange: [[-range, range], [-range, range], [-range, range]].slice(0, size)
  });
  clipCube = this.clipCube(view, {
    draw: true,
    hilite: size === 3
  });
  view.array({
    channels: 3,
    width: 1,
    live: false,
    data: [[0, 0, 0]]
  }).point({
    color: "black",
    size: 15,
    zIndex: 3
  });
  subspace = this.subspace({
    vectors: vectors,
    live: false,
    noPlane: size === 2,
    color: surfaceColor,
    lineOpts: {
      zOrder: 0
    },
    surfaceOpts: {
      zOrder: 1
    }
  });
  subspace.draw(clipCube.clipped);
  this.grid(clipCube.clipped, {
    vectors: vectors,
    live: false,
    lineOpts: {
      color: surfaceColor,
      opacity: .35
    }
  });
  this.labeledVectors(view, {
    name: 'basis',
    vectors: vectors,
    colors: [spanVecColor.arr(.9), spanVecColor.arr(.9), spanVecColor.arr(.9)].slice(0, numVecs),
    labels: labels,
    live: false,
    vectorOpts: {
      zIndex: 2
    },
    labelOpts: {
      zIndex: 3
    }
  });
  this.labeledPoints(view, {
    name: 'bandbhat',
    points: [vector, projection],
    colors: [bColor, bHatColor],
    labels: [vecLabel, vecLabel + "_Col(A)"],
    live: true,
    pointOpts: {
      zIndex: 4
    },
    labelOpts: {
      zIndex: 5
    }
  });
  view.array({
    width: 2,
    channels: 3,
    data: [vector, projection]
  }).line({
    color: [0.5, 0.5, 0.5],
    width: 3
  });
  linCombo = this.linearCombo(view, {
    coeffs: solution,
    coeffVars: [0, 1, 2],
    vectors: vectors,
    colors: [linComboColor, linComboColor, linComboColor],
    lineOpts: {
      zIndex: 3
    }
  });
  tmpVec = new THREE.Vector3();
  nulSpace = this.subspace({
    vectors: nulBasis
  });
  computeOut = (function(_this) {
    return function() {
      var i, j, particular, ref3;
      tmpVec.set(vector[0], vector[1], vector[2]);
      subspace.project(tmpVec, tmpVec);
      projection[0] = tmpVec.x;
      projection[1] = tmpVec.y;
      projection[2] = tmpVec.z;
      particular = solve(projection);
      if (particular[2] == null) {
        particular[2] = 0;
      }
      if (numVecs > subspace.dim) {
        tmpVec.set(solution[0] - particular[0], solution[1] - particular[1], solution[2] - particular[2]);
        nulSpace.project(tmpVec, tmpVec);
        solution[0] = tmpVec.x + particular[0];
        if (numVecs >= 2) {
          solution[1] = tmpVec.y + particular[1];
        }
        if (numVecs >= 3) {
          solution[2] = tmpVec.z + particular[2];
        }
      } else {
        for (i = j = 0, ref3 = solution.length; 0 <= ref3 ? j < ref3 : j > ref3; i = 0 <= ref3 ? ++j : --j) {
          solution[i] = particular[i];
        }
      }
      return updateCaptions();
    };
  })(this);
  this.draggable(view, {
    points: [vector],
    postDrag: computeOut
  });
  str = '<p><span id="vectoreqn-here"></span></p>';
  str += '<p><span id="matrixeqn-here"></span></p>';
  this.caption(str);
  vectorElt = document.getElementById('vectoreqn-here');
  matrixElt = document.getElementById('matrixeqn-here');
  updateCaptions = (function(_this) {
    return function() {
      var coeffColor, sign;
      a = solution[0].toFixed(2);
      coeffColor = linComboColor;
      str = ("\\color{" + (coeffColor.str()) + "}{" + a + "}\\, ") + ("\\color{" + (spanVecColor.str()) + "}{" + texLabels[0] + "}");
      if (numVecs >= 2) {
        if (solution[1] < 0) {
          sign = '';
        } else {
          sign = '+';
        }
        a = solution[1].toFixed(2);
        str += (sign + "\\color{" + (coeffColor.str()) + "}{" + a + "}\\, ") + ("\\color{" + (spanVecColor.str()) + "}{" + texLabels[1] + "}");
      }
      if (numVecs >= 3) {
        if (solution[2] < 0) {
          sign = '';
        } else {
          sign = '+';
        }
        a = solution[2].toFixed(2);
        str += (sign + "\\color{" + (coeffColor.str()) + "}{" + a + "}\\, ") + ("\\color{" + (spanVecColor.str()) + "}{" + texLabels[2] + "}");
      }
      str += "= \\color{" + (bHatColor.str()) + "}{" + vecLabel + "_{\\text{Col}(A)}}";
      katex.render(str, vectorElt);
      str = "A \\color{" + (coeffColor.str()) + "}{\\hat x} =";
      str += _this.texMatrix(matrix);
      str += _this.texVector(solution, {
        color: coeffColor
      });
      str += '=';
      str += _this.texVector(projection, {
        color: bHatColor
      });
      str += "= \\color{" + (bHatColor.str()) + "}{" + vecLabel + "_{\\text{Col}(A)}}";
      return katex.render(str, matrixElt);
    };
  })(this);
  return computeOut();
});


        });
    </script>
</body>
</html>

